#include "mysql_session_info.h"

#include "chat_session_info-odb.hxx"
#include "log.h"

namespace chat {
bool ChatSessionInfoTable::insert(ChatSessionInfomation& chat_session_info) {
    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        db_->persist(chat_session_info);

        // 提交事务
        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("新增会话信息[{}]失败: {}",
                  chat_session_info.chat_session_id(), e.what());

        return false;
    }

    return true;
}

bool ChatSessionInfoTable::remove(const std::string& chat_session_id) {
    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        // 删除会话数据的同时也要将会话成员数据删除
        db_->erase_query<ChatSessionInfomation>(
            odb::query<ChatSessionInfomation>::chat_session_id == chat_session_id);
        db_->erase_query<ChatSessionMember>(
            odb::query<ChatSessionMember>::session_id == chat_session_id);

        // 提交事务
        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("删除会话信息[{}]失败: {}", chat_session_id, e.what());

        return false;
    }

    return true;
}

bool ChatSessionInfoTable::remove(const std::string& user_id,
                                  const std::string& peer_id) {
    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        // 先获取单聊的会话信息，从而获取其会话id
        auto result = db_->query_one<SingleSessionInfo>(
            odb::query<SingleSessionInfo>::csi::chat_session_type ==
                (unsigned char)ChatSessionType::SINGLE &&
            odb::query<SingleSessionInfo>::csm1::user_id == user_id &&
            odb::query<SingleSessionInfo>::csm2::user_id == peer_id);

        std::string chat_session_id = result->chat_session_id;

        db_->erase_query<ChatSessionInfomation>(
            odb::query<ChatSessionInfomation>::chat_session_id == chat_session_id);
        db_->erase_query<ChatSessionMember>(
            odb::query<ChatSessionMember>::session_id == chat_session_id);

        // 提交事务
        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("删除单聊会话信息[{}-{}]失败: {}", user_id, peer_id,
                  e.what());

        return false;
    }

    return true;
}

ChatSessionInfomation ChatSessionInfoTable::sessionInfo(
    const std::string& chat_session_id) {
    ChatSessionInfomation chat_session_info;
    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        chat_session_info = *db_->query_one<ChatSessionInfomation>(
            odb::query<ChatSessionInfomation>::chat_session_id == chat_session_id);

        // 提交事务
        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("查询会话信息[{}]失败: {}", chat_session_id, e.what());

        return chat_session_info;
    }

    return chat_session_info;
}

std::vector<SingleSessionInfo> ChatSessionInfoTable::SingleSessionInfos(
    const std::string& user_id) {
    std::vector<SingleSessionInfo> signel_session_infos;
    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        odb::result<SingleSessionInfo> result = db_->query<SingleSessionInfo>(
            odb::query<SingleSessionInfo>::csi::chat_session_type ==
                (unsigned char)ChatSessionType::SINGLE &&
            odb::query<SingleSessionInfo>::csm1::user_id == user_id &&
            odb::query<SingleSessionInfo>::csm2::user_id !=
                odb::query<SingleSessionInfo>::csm1::user_id);

        for (const auto& signel_session_info : result) {
            signel_session_infos.push_back(signel_session_info);
        }

        // 提交事务
        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("查询用户[{}]单聊会话信息失败: {}", user_id, e.what());

        return signel_session_infos;
    }

    return signel_session_infos;
}

std::vector<GroupSessionInfo> ChatSessionInfoTable::groupSessionInfos(
    const std::string& user_id) {
    std::vector<GroupSessionInfo> group_session_infos;

    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        odb::result<GroupSessionInfo> result = db_->query<GroupSessionInfo>(
            odb::query<GroupSessionInfo>::csi::chat_session_type ==
                (unsigned char)ChatSessionType::GROUP &&
            odb::query<GroupSessionInfo>::csm::user_id == user_id);

        for (const auto& group_session_info : result) {
            group_session_infos.push_back(group_session_info);
        }

        // 提交事务
        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("查询用户[{}]群聊会话信息失败: {}", user_id, e.what());

        return group_session_infos;
    }

    return group_session_infos;
}
}  // namespace chat